package com.jmp.chat.tenxun;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.jmp.chat.*;
import lombok.extern.slf4j.Slf4j;
import one.stand.util.HttpUtil2;
import one.stand.util.OneListUtil;
import one.stand.util.RedisUtil;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author cjr
 */
@Slf4j
public class TenxunChatClient implements ChatClient {
    private static final String api_base = "https://console.tim.qq.com/";
    private static final long api_id = 1400360457L;
    private static final String api_key = "fd70b3149cf383291915d0a391cfb16c07ab3476c38067cbddc5366ac81748c3";
    private static final String api_admin = "admin";
    private static final long expire = 180 * 24 * 60 * 60;
    private TLSSigAPIv2 tlsSigAPIv2;

    private RedisUtil redisUtil;

    private String api_save = api_base + "v4/im_open_login_svc/account_import";
    private String api_update = api_base + "v4/profile/portrait_set";
    private String api_group_save = api_base + "v4/group_open_http_svc/create_group";
    private String api_group_remove = api_base + "v4/group_open_http_svc/destroy_group";
    private String api_group_info = api_base + "v4/group_open_http_svc/get_group_member_info";
    private String api_group_sys_msg = api_base + "v4/group_open_http_svc/send_group_system_notification";

    private String api_group_sendmsg = api_base + "v4/openim/sendmsg";

    public TenxunChatClient(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
        this.tlsSigAPIv2 = new TLSSigAPIv2(api_id, api_key);

        String paramsPublic = "?sdkappid=" + api_id + "&identifier=" + api_admin + "&usersig=";
        this.api_save = api_save + paramsPublic;
        this.api_update = api_update + paramsPublic;
        this.api_group_save = api_group_save + paramsPublic;
        this.api_group_remove = api_group_remove + paramsPublic;
        this.api_group_info = api_group_info + paramsPublic;
        this.api_group_sys_msg = api_group_sys_msg + paramsPublic;
        this.api_group_sendmsg = api_group_sendmsg + paramsPublic;
    }

    @Override
    public boolean save(ChatSaveRequest savePo) {

        //insert
        TenxunChatSaveRequest saveDto = TenxunChatSaveRequest.builder()
                .Identifier(savePo.getUserId())
                .Nick(savePo.getNickName())
                .FaceUrl(savePo.getPic())
                .build();
        String request = JSON.toJSONString(saveDto);
        String response = null;
        try {
            response = HttpUtil2.post(this.api_save + getPwd(api_admin) + getRandom(), request);
            TenxunChatResult result = JSON.parseObject(response, TenxunChatResult.class);
            if (result.isSuccess()) {
                return true;
            } else {
                log.warn("save({}) result: {}", request, response);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            if (Objects.nonNull(response)) {
                log.warn("save({}) result: {}", request, response);
            }
        }

        return false;
    }

    @Override
    public String getPwd(String user) {
        String key = "login:chat:tenxun:" + user;
        String sign = redisUtil.get(key);
        if (StringUtils.isNoneBlank(sign)) return sign;

        sign = tlsSigAPIv2.genSig(user, expire);
        redisUtil.set(key, sign, 100, TimeUnit.DAYS);
        return sign;
    }

    @Override
    public boolean sendmsg(ChatSendmsgPo po) {
        com.jmp.chat.tenxun.TenxunChatSendmsgRequest.MsgBody msgBody;
        if (po.isCustom()) {
            msgBody = com.jmp.chat.tenxun.TenxunChatSendmsgRequest.MsgBody.builder()
                    .MsgType("TIMCustomElem")//自定义消息
                    .MsgContent(TenxunChatSendmsgRequest.MsgContentCustomer.builder()
                            .Data(po.getContent())
                            .build())
                    .build();
        } else {
            msgBody = com.jmp.chat.tenxun.TenxunChatSendmsgRequest.MsgBody.builder()
                    .MsgType("TIMTextElem")//文本消息
                    .MsgContent(TenxunChatSendmsgRequest.MsgContent.builder()
                            .Text(po.getContent())
                            .build())
                    .build();
        }
        TenxunChatSendmsgRequest saveDto = TenxunChatSendmsgRequest.builder()
                .SyncOtherMachine(2)//2:不将消息同步至From_Account
                .From_Account(po.getFromUser())
                .To_Account(po.getToUser())
                .MsgLifeTime(604800)//604800:7天
                .MsgRandom(RandomUtil.randomInt(999999))
                .MsgBody(Lists.newArrayList(msgBody))
                .OfflinePushInfo(TenxunChatSendmsgRequest.OfflinePushInfo.builder()
                        .PushFlag(0)
                        .Title("系统消息")
                        .Desc(po.getMsgContent())
                        .Ext(po.getContent())
                        .ApnsInfo(TenxunChatSendmsgRequest.ApnsInfo.builder()
                                .BadgeMode(1)
                                .build())
                        .build())
                .build();
        String request = JSON.toJSONString(saveDto);
        String response = null;
        try {
            response = HttpUtil2.post(this.api_group_sendmsg + getPwd(api_admin) + getRandom(), request);
            TenxunChatResult result = JSON.parseObject(response, TenxunChatResult.class);
            if (result.isSuccess()) {
                return true;
            } else {
                log.warn("save({}) result: {}", request, response);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            if (Objects.nonNull(response)) {
                log.warn("saveGroup({}) result: {}", request, response);
            }
        }
        return false;
    }

    @Override
    public String saveGroup(ChatGroupSaveRequest chatGroupSaveRequest) {
        TenxunChatGroupSaveRequest saveDto = TenxunChatGroupSaveRequest.builder()
                .Type("AVChatRoom")
                .Name(chatGroupSaveRequest.getName())
                .build();
        String request = JSON.toJSONString(saveDto);
        String response = null;
        try {
            response = HttpUtil2.post(this.api_group_save + getPwd(api_admin) + getRandom(), request);
            TenxunChatGroupSaveResult result = JSON.parseObject(response, TenxunChatGroupSaveResult.class);
            if (result.isSuccess()) {
                return result.getGroupId();
            } else {
                log.warn("saveGroup({}) result: {}", request, response);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            if (Objects.nonNull(response)) {
                log.warn("saveGroup({}) result: {}", request, response);
            }
        }
        return null;
    }

    @Override
    public boolean groupRemove(ChatGroupRemoveRequest po) {
        //insert
        TenxunChatGroupRemoveRequest saveDto = TenxunChatGroupRemoveRequest.builder()
                .GroupId(po.getGroupId())
                .build();
        String request = JSON.toJSONString(saveDto);
        String response = null;
        try {
            response = HttpUtil2.post(this.api_group_remove + getPwd(api_admin) + getRandom(), request);
            TenxunChatResult result = JSON.parseObject(response, TenxunChatResult.class);
            if (result.isSuccess()) {
                return true;
            } else {
                log.warn("groupRemove({}) result: {}", request, response);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            if (Objects.nonNull(response)) {
                log.warn("groupRemove({}) result: {}", request, response);
            }
        }

        return false;
    }

    @Override
    public ChatGroupInfoResponse groupInfo(ChatGroupInfoRequest po) {
        //insert
        TenxunChatGroupInfoRequest saveDto = TenxunChatGroupInfoRequest.builder()
                .GroupId(po.getGroupId())
                .Limit(3)
                .Offset(0)
                .build();
        String request = JSON.toJSONString(saveDto);
        String response = null;
        try {
            response = HttpUtil2.post(this.api_group_info + getPwd(api_admin) + getRandom(), request);
            TenxunChatGroupInfoResult result = JSON.parseObject(response, TenxunChatGroupInfoResult.class);
            if (result.isSuccess()) {
                List<String> membeList = OneListUtil.isNotEmpty(result.getMemberList()) ? result.getMemberList().stream().map(TenxunChatGroupInfoResult.Member::getMember_Account).collect(Collectors.toList()) : null;
                return ChatGroupInfoResponse.builder()
                        .memberNum(result.getMemberNum())
                        .memberList(membeList)
                        .build();
            } else {
                log.warn("groupInfo({}) result: {}", request, response);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            if (Objects.nonNull(response)) {
                log.warn("groupInfo({}) result: {}", request, response);
            }
        }

        return null;
    }

    @Override
    public boolean groupSystemMsg(ChatGroupSystemMsgPo po) {

        //insert
        TenxunChatGroupSystemMsgRequest saveDto = TenxunChatGroupSystemMsgRequest.builder()
                .GroupId(po.getGroupId())
                .Content(po.getContent())
                .build();
        String request = JSON.toJSONString(saveDto);
        String response = null;
        try {
            response = HttpUtil2.post(this.api_group_sys_msg + getPwd(api_admin) + getRandom(), request);
            TenxunChatResult result = JSON.parseObject(response, TenxunChatResult.class);
            if (result.isSuccess()) {
                return true;
            } else {
                log.warn("groupSystemMsg({}) result: {}", request, response);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            if (Objects.nonNull(response)) {
                log.warn("groupSystemMsg({}) result: {}", request, response);
            }
        }

        return false;
    }

    private String getRandom() {
        return "&random=" + RandomUtil.randomInt(1, 429496729) + "&contenttype=json";
    }
}
